//
//  previewController.m
//  RecognizeCard
//
//  Created by sense on 2021/8/10.
//  Copyright © 2021 谭高丰. All rights reserved.
//
#define KScreenWidth  [UIScreen mainScreen].bounds.size.width
#define KScreenHeight  [UIScreen mainScreen].bounds.size.height

#import "previewController.h"
//导入相机框架
#import <AVFoundation/AVFoundation.h>
#import <Photos/Photos.h>
//将拍摄好的照片写入系统相册中，所以我们在这里还需要导入一个相册需要的头文件iOS8
#import <Photos/Photos.h>
#import "RecogizeCardManager.h"


@interface previewController ()<AVCaptureVideoDataOutputSampleBufferDelegate>

@property (nonatomic,strong) AVCaptureSession *captureSession;
@property (nonatomic,strong) AVCaptureDeviceInput *deviceInput;
@property (nonatomic,strong) AVCaptureStillImageOutput *imageOutput;
@property (nonatomic,strong) AVCaptureVideoDataOutput * videoDataOutput;
@property (nonatomic,strong) AVCaptureVideoPreviewLayer *previewLayer;
@property (nonatomic,strong) AVCaptureDevice *captureDevice;

@property (nonatomic, strong) UIImageView *imageView1;
@property (nonatomic, strong) UIImageView *imageView2;
@property (nonatomic, strong) UIImageView *imageView3;

@property (nonatomic, strong) UIView *rangeView;
@property (nonatomic, strong) UIView *borderView;

@property (nonatomic,strong) UIImage * currentImage;

@property (nonatomic, strong) NSTimer *timer;

@property (nonatomic, assign) int unlegalNum;


@end

@implementation previewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor clearColor];
    [self setUpCameraPreviewLayer];
    [self startCamera];
    
    // 设置初始闪光灯为关闭状态
    if ([self.captureDevice lockForConfiguration:nil]) {
        if ([self.captureDevice isFlashModeSupported:AVCaptureFlashModeOff]) {
            [self.captureDevice setFlashMode:AVCaptureFlashModeOff];
        }
        [self.captureDevice unlockForConfiguration];
    }
    
    
    [self setUI];
    
    self.unlegalNum = 0;
    
    
    
    
}

- (void)setUI{
    UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(30, 30, 50, 30)];
    [button addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    button.backgroundColor = [UIColor redColor];
    [button setTitle:@"返回" forState:UIControlStateNormal];
    [self.view addSubview:button];
    
    self.imageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(30, 500, 100, 180)];
    self.imageView1.backgroundColor = [UIColor greenColor];
    [self.view addSubview:self.imageView1];

    self.imageView2 = [[UIImageView alloc]initWithFrame:CGRectMake(150, 500, 100, 180)];
    self.imageView2.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:self.imageView2];

    self.imageView3 = [[UIImageView alloc]initWithFrame:CGRectMake(270, 500, 100, 80)];
    self.imageView3.backgroundColor = [UIColor purpleColor];
    [self.view addSubview:self.imageView3];

    self.rangeView = [[UIView alloc]initWithFrame:CGRectMake(30, 190, 315, 200)];
    self.rangeView.backgroundColor = [UIColor clearColor];
    [self setBorderWithView:self.rangeView top:true left:true bottom:true right:true borderColor:[UIColor lightGrayColor] ];
    [self.view addSubview:self.rangeView];

//    self.borderView = [[UIView alloc]initWithFrame:CGRectZero];
//    self.borderView.backgroundColor = [UIColor clearColor];
//    self.borderView.layer.borderColor = [UIColor blueColor].CGColor;
//    self.borderView.layer.borderWidth = 2;
//    [self.view addSubview:self.borderView];
    
    [self setTimer];
}

- (void)back{
    [self.timer invalidate];
    [self dismissViewControllerAnimated:YES completion:nil];
}


- (void)setUpCameraPreviewLayer {
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    //相机权限无权限访问
    if ((authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied) && (authStatus != AVAuthorizationStatusNotDetermined)) {

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"“demo”想访问您的相机"]
                                                        message:@"开启后，可使用拍照拍摄功能"
                                                       delegate:self
                                              cancelButtonTitle:@"不允许"
                                              otherButtonTitles:@"好", nil];
        [alert show];
        
    }
    
    if (!_previewLayer) {
        [self initSession];
        self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
        self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspect;
        self.previewLayer.frame = CGRectMake((CGRectGetWidth(self.view.bounds)-KScreenWidth)/2, (CGRectGetHeight(self.view.bounds)-KScreenHeight)/2, KScreenWidth, KScreenHeight);
        [self.view.layer insertSublayer:self.previewLayer atIndex:0];
    }
    self.view.layer.masksToBounds = YES;
}

- (void)initSession {
//    self.captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    self.captureDevice = [self cameraWithDirection:AVCaptureDevicePositionBack];
    self.captureSession = [[AVCaptureSession alloc] init];
    if ([self.captureSession canSetSessionPreset:AVCaptureSessionPreset1920x1080]) {
        [self.captureSession setSessionPreset:AVCaptureSessionPreset1920x1080];
    }
    self.deviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:self.captureDevice error:nil];
//    self.imageOutput = [[AVCaptureStillImageOutput alloc]init];
//    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey, nil];
//    [self.imageOutput setOutputSettings:outputSettings];
    if ([self.captureSession canAddInput:self.deviceInput]) {
        [self.captureSession addInput:self.deviceInput];
    }
//    if ([self.captureSession canAddOutput:self.imageOutput]) {
//        [self.captureSession addOutput:self.imageOutput];
//    }
    if ([self.captureSession canAddOutput:self.videoDataOutput]) {
        [self.captureSession addOutput:self.videoDataOutput];
    }
    
    AVCaptureConnection * videoConnection = [self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo];
    if (videoConnection ==  nil) {
        return;
    }
//    if ([_orientation isEqualToString:@"horizontal"]) {//横屏拍摄框
//        videoConnection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;//控制输出照片方向
//    }else{//竖屏拍摄框
//        videoConnection.videoOrientation = AVCaptureVideoOrientationPortrait;//控制输出照片方向
//    }
    videoConnection.videoOrientation = AVCaptureVideoOrientationPortrait;//控制输出照片方向
}
- (AVCaptureDevice *)cameraWithDirection:(AVCaptureDevicePosition)position {
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in devices) {
        if ([device position] == position) {
            return device;
        }
    }
    return nil;
}

- (void)startCamera
{
    if (self.captureSession) {
        [self.captureSession startRunning];
    }
}

- (void)setTimer{
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(countDown) userInfo:nil repeats:YES];
    [self.timer fire];
}

- (void)countDown{
    [self shutterCamera];
}

- (AVCaptureVideoDataOutput *)videoDataOutput{
    if (_videoDataOutput == nil) {
        _videoDataOutput = [[AVCaptureVideoDataOutput alloc]init];
        [_videoDataOutput setVideoSettings:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id)kCVPixelBufferPixelFormatTypeKey]];
        _videoDataOutput.alwaysDiscardsLateVideoFrames = YES;
        dispatch_queue_t queue = dispatch_queue_create("VideoQueue", NULL);
        [_videoDataOutput setSampleBufferDelegate:self queue:queue];
    }
    return _videoDataOutput;
}

- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    // 第一种方式 转存图片
    if (sampleBuffer) {
        self.currentImage = [self imageFromSampleBuffer:sampleBuffer];
    }
    
    // 第二种方式 直接存buffer
//    if (sampleBuffer){
//        self.bufferRef = sampleBuffer;
//    }
}

//CMSampleBufferRef转NSImage
-(UIImage *)imageFromSampleBuffer:(CMSampleBufferRef)sampleBuffer{
     // 为媒体数据设置一个CMSampleBuffer的Core Video图像缓存对象
     CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
     // 锁定pixel buffer的基地址
     CVPixelBufferLockBaseAddress(imageBuffer, 0);
     // 得到pixel buffer的基地址
     void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
     // 得到pixel buffer的行字节数
     size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
     // 得到pixel buffer的宽和高
     size_t width = CVPixelBufferGetWidth(imageBuffer);
     size_t height = CVPixelBufferGetHeight(imageBuffer);
     // 创建一个依赖于设备的RGB颜色空间
     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
     // 用抽样缓存的数据创建一个位图格式的图形上下文（graphics context）对象
     CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
     // 根据这个位图context中的像素数据创建一个Quartz image对象
     CGImageRef quartzImage = CGBitmapContextCreateImage(context);
     // 解锁pixel buffer
     CVPixelBufferUnlockBaseAddress(imageBuffer,0);
     // 释放context和颜色空间
     CGContextRelease(context); CGColorSpaceRelease(colorSpace);
     // 用Quartz image创建一个UIImage对象image
     UIImage *image = [UIImage imageWithCGImage:quartzImage];
     // 释放Quartz image对象
     CGImageRelease(quartzImage);
     return (image);
    
//    NSData *imageData =  [AVCapturePhotoOutput JPEGPhotoDataRepresentationForJPEGSampleBuffer:sampleBuffer previewPhotoSampleBuffer:sampleBuffer];
//    UIImage*image = [UIImage imageWithData:imageData];
//    return image;
}

- (void)shutterCamera
{
//    AVCaptureConnection * videoConnection = [self.imageOutput connectionWithMediaType:AVMediaTypeVideo];
//    if (videoConnection ==  nil) {
//        return;
//    }
//    if ([_orientation isEqualToString:@"horizontal"]) {//横屏拍摄框
//        videoConnection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;//控制输出照片方向
//    }else{//竖屏拍摄框
//        videoConnection.videoOrientation = AVCaptureVideoOrientationPortrait;//控制输出照片方向
//    }
    
//    [self.imageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
//
//        if (imageDataSampleBuffer == nil) {
//            return;
//        }
//        NSString *tmpPath = NSTemporaryDirectory();
//        NSDate *date=[NSDate date];
//        NSString* fileName = [NSString stringWithFormat:@"%ld.jpg",(long int)date.timeIntervalSince1970];
//        NSString* filePath = [tmpPath stringByAppendingPathComponent:fileName];
//
//        NSData *imageData =  [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
//        UIImage*image = [UIImage imageWithData:imageData];
//        UIImage *image11 = [[UIImage alloc] init];
//
//        image11 =[self cropImage:[self fixOrientation:image]];
//
//        NSLog(@"image:%@", image11);
        
//        self.imageView1.image = image11;
        
//        [self judgeImage:image11];
        
        
//        NSData *fileImageData = UIImageJPEGRepresentation(image11, 0.5);
//        NSString *pictureDataString=[fileImageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
//        [fileImageData writeToFile:filePath atomically:YES];
//        if (callback) {
//            callback(@{@"path":[NSURL fileURLWithPath:filePath].absoluteString,@"file":pictureDataString});
//        }
//    }];
    
    if (self.currentImage){
        UIImage*image11 = [UIImage imageWithData:UIImageJPEGRepresentation(self.currentImage, 0.5)];
//        image11 =[self cropImage:[self fixOrientation:image11]];
        image11 =[self fixOrientation:image11];
        self.imageView1.image = image11;
        [self judgeImage:image11];
    }
    
}

- (void)judgeImage:(UIImage *)image11{
    [[RecogizeCardManager recognizeCardManager] testRecognizeCardWithImage:image11 compleate:^(NSDictionary *dic) {
        
        self.imageView2.image = dic[@"dealAgo"];
        self.imageView3.image = dic[@"dealAfter"];
        NSValue *value = dic[@"range"];
        CGRect range = value.CGRectValue;
        
        int x = KScreenWidth * range.origin.x / image11.size.width;
        int y = KScreenHeight * range.origin.y / image11.size.height;
        int width = KScreenWidth * range.size.width / image11.size.width;
        int height = KScreenHeight * range.size.height / image11.size.height;
        
        if(width == 0 || height == 0){
            self.unlegalNum ++;
            if (self.unlegalNum == 5){
                [self setBorderWithView:self.rangeView top:true left:true bottom:true right:true borderColor:[UIColor redColor] ];
                self.unlegalNum = 0;
            }
            return;
        }
        self.unlegalNum = 0;
        
        NSLog(@"range-x:%f", range.origin.x);
        NSLog(@"range-y:%f", range.origin.y);
        NSLog(@"range-width:%f", range.size.width);
        NSLog(@"range-height:%f", range.size.height);
        NSLog(@"");
        
//        self.borderView.frame = CGRectMake(x, y, width, height);
        
        [self judgeBorderWithX:x y:y width:width height:height];
        
    }];
}

- (BOOL)judgePoint:(CGPoint)point InRange:(CGRect)range{
    if (range.origin.x < point.x &&
        range.origin.x + range.size.width > point.x &&
        range.origin.y < point.y &&
        range.origin.y + range.size.height > point.y
        )
    {
        return true;
    }
    return false;
}

- (void)judgeBorderWithX:(CGFloat)x y:(CGFloat)y width:(CGFloat)width height:(CGFloat)height{
    CGPoint leftTopPoint = CGPointMake(x, y);
    CGPoint leftBottomPoint = CGPointMake(x, y + height);
    CGPoint rightTopPoint = CGPointMake(x + width, y);
    CGPoint rightBottomPoint = CGPointMake(x + width, y + height);
    
    // 检测上边框
    if ([self judgePoint:leftTopPoint InRange:self.rangeView.frame] || [self judgePoint:rightTopPoint InRange:self.rangeView.frame]){
        [self setBorderWithView:self.rangeView top:true left:false bottom:false right:false borderColor:[UIColor greenColor] ];
    } else {
        [self setBorderWithView:self.rangeView top:true left:false bottom:false right:false borderColor:[UIColor redColor] ];
    }
    
    // 检测下边框
    if ([self judgePoint:leftBottomPoint InRange:self.rangeView.frame] || [self judgePoint:rightBottomPoint InRange:self.rangeView.frame]){
        [self setBorderWithView:self.rangeView top:false left:false bottom:true right:false borderColor:[UIColor greenColor] ];
    } else {
        [self setBorderWithView:self.rangeView top:false left:false bottom:true right:false borderColor:[UIColor redColor] ];
    }
    
    // 检测左边框
    if ([self judgePoint:leftTopPoint InRange:self.rangeView.frame] || [self judgePoint:leftBottomPoint InRange:self.rangeView.frame]){
        [self setBorderWithView:self.rangeView top:false left:true bottom:false right:false borderColor:[UIColor greenColor] ];
    } else {
        [self setBorderWithView:self.rangeView top:false left:true bottom:false right:false borderColor:[UIColor redColor] ];
    }
    
    // 检测右边框
    if ([self judgePoint:rightTopPoint InRange:self.rangeView.frame] || [self judgePoint:rightBottomPoint InRange:self.rangeView.frame]){
        [self setBorderWithView:self.rangeView top:false left:false bottom:false right:true borderColor:[UIColor greenColor] ];
    } else {
        [self setBorderWithView:self.rangeView top:false left:false bottom:false right:true borderColor:[UIColor redColor] ];
    }
}


// 以图片中心为中心,裁剪图片
-(UIImage *)cropImage:(UIImage *)image{
    
    CGImageRef sourceImageRef = [image CGImage];//将UIImage转换成CGImageRef
    
    CGFloat _imageWidth = image.size.width * image.scale;
    CGFloat _imageHeight = image.size.height * image.scale;
    CGFloat  width = _imageWidth * CGRectGetWidth(self.view.bounds)/KScreenWidth;
    CGFloat  height = _imageWidth * CGRectGetHeight(self.view.bounds)/KScreenWidth;
    
    CGRect rect = CGRectMake((_imageWidth - width)/2, (_imageHeight - height)/2, width, height);
    CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);//按照给定的矩形区域进行剪裁
    UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
    
    return newImage;
}

// 判断图片是否翻转
- (UIImage *)fixOrientation:(UIImage *)aImage {
    
    // No-op if the orientation is already correct
    if (aImage.imageOrientation == UIImageOrientationUp)
        return aImage;
    
    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    CGAffineTransform transform = CGAffineTransformIdentity;
    
    switch (aImage.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;
            
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;
            
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        default:
            break;
    }
    
    switch (aImage.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
            
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        default:
            break;
    }
    
    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
                                             CGImageGetBitsPerComponent(aImage.CGImage), 0,
                                             CGImageGetColorSpace(aImage.CGImage),
                                             CGImageGetBitmapInfo(aImage.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (aImage.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
            break;
            
        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
            break;
    }
    
    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}

- (void)setBorderWithView:(UIView *)view
                      top:(BOOL)top
                     left:(BOOL)left
                   bottom:(BOOL)bottom
                    right:(BOOL)right
              borderColor:(UIColor *)borderColor
{
    CGFloat width = 5;
    if (top) {
        CALayer *layer = [CALayer layer];
        layer.frame = CGRectMake(0, 0, view.frame.size.width, width);
        layer.backgroundColor =  borderColor.CGColor;
        [view.layer addSublayer:layer];
    }
    if (left) {
        CALayer *layer = [CALayer layer];
        layer.frame = CGRectMake(0, 0, width, view.frame.size.height);
        layer.backgroundColor =  borderColor.CGColor;
        [view.layer addSublayer:layer];
    }
    if (bottom) {
        CALayer *layer = [CALayer layer];
        layer.frame = CGRectMake(0, view.frame.size.height - width, view.frame.size.width, width);
        layer.backgroundColor =  borderColor.CGColor;
        [view.layer addSublayer:layer];
    }
    if (right) {
        CALayer *layer = [CALayer layer];
        layer.frame = CGRectMake(view.frame.size.width - width, 0, width, view.frame.size.height);
        layer.backgroundColor =  borderColor.CGColor;
        [view.layer addSublayer:layer];
    }
}
@end
